package com.ylr.admin.framework.controller.web;

import java.util.List;
import java.util.Objects;

import com.ylr.base.common.annotation.Resubmit;
import com.ylr.base.common.constant.Constant;
import com.ylr.base.common.dto.PageDto;
import com.ylr.admin.common.dto.dept.DeptDto;
import com.ylr.admin.common.dto.dept.DeptEnumDto;
import com.ylr.base.common.enums.CommonEnum;
import com.ylr.admin.common.enums.DeptEnum;
import com.ylr.base.common.jsr303.group.Save;
import com.ylr.base.common.jsr303.group.Search;
import com.ylr.base.common.jsr303.group.Update;
import com.ylr.base.common.tool.Result;
import com.ylr.base.common.vo.UpdateStatusVo;
import com.ylr.admin.common.vo.dept.DeptFormVo;
import com.ylr.admin.common.vo.dept.DeptVo;
import com.ylr.admin.framework.service.DeptService;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Size;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wyw
 * date: 2023-04-21 11:27:23
 * className: DeptController 部门web端请求接口类
 * version: 1.0
 * description:
 */
@RestController
@RequestMapping("/web/dept")
@AllArgsConstructor
public class DeptWebController {

    private static final Logger log = LoggerFactory.getLogger(DeptWebController.class);

    private final DeptService deptService;

    /**
     * 保存部门接口
     * <p>
     * 此接口会校验是否重复提交
     * @param deptVo 参数对象
     */
    @Resubmit(message = "保存部门")
    @PostMapping("/save")
    public Result<Object> saveDept(@Validated(Save.class) @RequestBody DeptVo deptVo) {
        log.info("web => 开始保存部门操作。{}", deptVo);

        if (DeptEnum.isLevelFail(deptVo.getLevel())) {
            String msg = "部门等级值错误";
            log.info(msg);
            return Result.requestFail(msg);
        }

        deptService.saveDept(deptVo);

        log.info("web => 保存部门操作结束");
        return Result.success();
    }

    /**
     * 分页查询部门列表接口
     * @param deptFormVo 参数对象
     * @return 部门分页数据
     */
    @PostMapping("/page/list")
    public Result<PageDto<DeptDto>> pageDeptList(@Validated(Search.class) @RequestBody DeptFormVo deptFormVo) {
        log.info("web => 开始分页查询部门列表操作。{}", deptFormVo);

        PageDto<DeptDto> pageDto = deptService.pageDeptList(deptFormVo);

        log.info("web => 分页查询部门列表操作操作");
        return Result.success(pageDto);
    }

    /**
     * 获取部门数据接口
     * @param id 主键
     * @return 部门数据
     */
    @GetMapping("/get")
    public Result<DeptDto> getDept(@RequestParam("id") Long id){
        log.info("web => 开始获取部门数据操作。id={}", id);

        DeptDto deptDto = deptService.getDept(id);

        log.info("web => 获取部门数据操作结束");
        return Result.success(deptDto);
    }

    /**
     * 获取子部门下一个排序等级接口
     * 根据父级主键，获取其子部门的下一个排序等级
     * @param parentId 父级主键
     * @return 排序等级数值
     */
    @GetMapping("/next/sort")
    public Result<Integer> getNextSort(@RequestParam("parentId") Long parentId) {
        log.info("web => 开始获取子部门下一个排序等级操作。parentId={}", parentId);

        Integer sort = deptService.getNextSort(parentId);

        log.info("web => 获取子部门下一个排序等级操作结束");
        return Result.success(sort);
    }

    /**
     * 获取部门结构树接口
     * 所有有效部门组成的结构树数据
     * @return 部门结构树数据
     */
    @GetMapping("/tree")
    public Result<DeptDto> getDeptTree() {
        log.info("开始获取部门结构树操作");

        DeptDto deptDto = deptService.getDeptTree();

        log.info("开获取部门结构树操作结束");
        return Result.success(deptDto);
    }

    /**
     * 获取父级部门接口
     * 根据部门主键，获取其所有父级及其父父级部门
     * @param id    部门主键
     * @param order 排序方式[0-顶级父级到直接父级 1-直接父级到顶级父级]
     * @return 父级部门列表
     */
    @GetMapping("/parent/list")
    public Result<List<DeptDto>> getParentDeptList(@RequestParam("id") Long id,
                                                   @RequestParam(value = "order", required = false) Integer order) {
        log.info("web => 开始获取父级部门操作。id={} order={}", id, order);
        if (Objects.isNull(order)) {
            order = Constant.ZERO;
        }
        List<DeptDto> deptList = deptService.getParentDeptList(id, order);

        log.info("web => 获取父级部门操作结束");
        return Result.success(deptList);
    }

    /**
     * 获取子部门结构树接口
     * 如果传递父级主键，则获取其子部门结构树
     * @param parentId 父级主键
     * @return 部门结构树数据
     */
    @GetMapping("/children/tree")
    public Result<List<DeptDto>> getChildrenDeptTree(@RequestParam("parentId") Long parentId) {
        log.info("web => 开始获取子部门结构树操作。parentId={}", parentId);

        List<DeptDto> deptDtoList = deptService.getChildrenDeptTree(parentId);

        log.info("web => 获取子部门结构树操作结束");
        return Result.success(deptDtoList);
    }

    /**
     * 获取部门页面枚举数据接口
     * @return 页面枚举数据
     */
    @GetMapping("/page/enums")
    public Result<DeptEnumDto> getPageEnums() {
        log.info("web => 开始获取部门页面枚举数据操作");

        DeptEnumDto deptEnumDto = deptService.getPageEnums();

        log.info("web => 获取页面枚举数据操作结束");
        return Result.success(deptEnumDto);
    }

    /**
     * 修改部门接口
     * <p>
     * 此接口会校验是否重复提交
     * @param deptVo 参数对象
     */
    @Resubmit(message = "修改部门")
    @PostMapping("/update")
    public Result<Object> updateDept(@Validated(Update.class) @RequestBody DeptVo deptVo){
        log.info("web => 开始修改部门操作。{}", deptVo);
        if (DeptEnum.isLevelFail(deptVo.getLevel())) {
            String msg = "部门等级值错误";
            log.info(msg);
            return Result.requestFail(msg);
        }

        deptService.updateDept(deptVo);

        log.info("web => 修改部门操作结束");
        return Result.success();
    }

    /**
     * 修改部门状态接口
     * <p>
     * 此接口会校验是否重复提交
     * @param updateStatusVo 参数对象
     */
    @Resubmit(message = "修改部门状态")
    @PostMapping("/update/status")
    public Result<Object> updateDeptStatus(@Validated @RequestBody UpdateStatusVo updateStatusVo) {
        log.info("web => 开始修改部门状态操作。{}", updateStatusVo);

        CommonEnum statusEnum = CommonEnum.getStatusEnum(updateStatusVo.getStatus());
        if (Objects.isNull(statusEnum)) {
            log.info("部门状态值错误");
            return Result.requestFail("部门状态值错误");
        }

        deptService.updateDeptStatus(updateStatusVo);

        log.info("web => 修改部门状态操作结束");
        return Result.success();
    }

    /**
     * 删除部门接口
     * <p>
     * 此接口会校验是否重复提交
     * @param idList 主键列表
     */
    @Resubmit(message = "删除部门")
    @DeleteMapping("/delete")
    public Result<Object> deleteDept(@Size(min = 1, message = "主键列表不能为空") @RequestBody List<Long> idList){
        log.info("web => 开始删除部门操作。idList={}", idList);

        deptService.deleteDept(idList);

        log.info("web => 删除部门操作结束");
        return Result.success();
    }

}
